package com.bc.bccore.util;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/**
 * Created by lianzerong on 2018/8/12.
 */
public class DateUtil  extends DateUtils {

    /** logger */
    private static final Logger logger = LoggerFactory.getLogger(DateUtil.class);

    /** yyyyMMdd */
    public final static String SHORT_FORMAT = "yyyyMMdd";

    /** yyyyMMddHHmmss */
    public final static String LONG_FORMAT = "yyyyMMddHHmmss";

    /** yyyy-MM-dd */
    public final static String WEB_FORMAT = "yyyy-MM-dd";

    /** HHmmss */
    public final static String TIME_FORMAT = "HHmmss";

    /** yyyyMM */
    public final static String MONTH_FORMAT = "yyyyMM";

    /** yyyy年MM月dd日 */
    public final static String CHINA_FORMAT = "yyyy年MM月dd日";

    /**
     * yyyy年MM月dd日 HH:mm
     */
    public final static String LONG_CHINA_FORMAT = "yyyy年MM月dd日 HH:mm";

    /**
     * yyyy年MM月dd日 HH:mm
     */
    public final static String LONG_WEB_CHINA_FORMAT = "yyyy年MM月dd日 HH:mm:ss";

    /** yyyy-MM-dd HH:mm:ss */
    public final static String LONG_WEB_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /** yyyy-MM-dd HH:mm */
    public final static String LONG_WEB_FORMAT_NO_SEC = "yyyy-MM-dd HH:mm";

    /**
     * 日期减少
     *
     * @param start 开始时间
     * @param minutes 分钟数
     * @return
     */
    public static Date minusMinutes(Date start, int minutes) {
        DateTime newDate = new DateTime(start).minusMinutes(minutes);
        return newDate.toDate();
    }

    /**
     * 日期对象解析成日期字符串基础方法，可以据此封装出多种便捷的方法直接使用
     *
     * @param date 待格式化的日期对象
     * @param format 输出的格式
     * @return 格式化的字符串
     */
    public static String format(Date date, String format) {
        if (date == null || StringUtils.isBlank(format)) {
            return StringUtils.EMPTY;
        }
        return new DateTime(date).toString(format, Locale.SIMPLIFIED_CHINESE);
    }

    /**
     * 格式化当前时间
     *
     * @param format 输出的格式
     * @return
     */
    public static String formatCurrent(String format) {
        if (StringUtils.isBlank(format)) {
            return StringUtils.EMPTY;
        }
        return new DateTime().toString(format, Locale.SIMPLIFIED_CHINESE);
    }

    /**
     * 日期字符串解析成日期对象基础方法，可以在此封装出多种便捷的方法直接使用
     *
     * @param dateStr 日期字符串
     * @param format 输入的格式
     * @return 日期对象
     * @throws ParseException
     */
    public static Date parse(String dateStr, String format) throws IllegalArgumentException {
        return DateTimeFormat.forPattern(format).withLocale(Locale.SIMPLIFIED_CHINESE).parseDateTime(dateStr).toDate();
    }

    /**
     * 日期字符串解析成日期对象基础方法，可以在此封装出多种便捷的方法直接使用
     *
     * @param dateStr 日期字符串
     * @return 日期对象
     * @throws ParseException
     */
    public static Date parseLongFormat(String dateStr) throws IllegalArgumentException {
        int formatLength = StringUtils.length(DateUtil.LONG_FORMAT);
        dateStr = StringUtils.rightPad(dateStr, formatLength, "0");
        return parse(dateStr, LONG_FORMAT);
    }

    /**
     * 日期字符串格式化基础方法，可以在此封装出多种便捷的方法直接使用
     *
     * @param dateStr 日期字符串
     * @param formatIn 输入的日期字符串的格式
     * @param formatOut 输出日期字符串的格式
     * @return 已经格式化的字符串
     * @throws ParseException
     */
    public static String format(String dateStr, String formatIn, String formatOut) throws IllegalArgumentException {
        Date date = parse(dateStr, formatIn);
        return format(date, formatOut);
    }

    /**
     * 把日期对象按照<code>yyyyMMdd</code>格式解析成字符串
     *
     * @param date 待格式化的日期对象
     * @return 格式化的字符串
     */
    public static String formatShort(Date date) {
        return format(date, SHORT_FORMAT);
    }

    /**
     * 把日期字符串按照<code>yyyyMMdd</code>格式，进行格式化
     *
     * @param dateStr 待格式化的日期字符串
     * @param formatIn 输入的日期字符串的格式
     * @return 格式化的字符串
     */
    public static String formatShort(String dateStr, String formatIn) throws IllegalArgumentException {
        return format(dateStr, formatIn, SHORT_FORMAT);
    }

    /**
     * 把日期对象按照<code>yyyy-MM-dd</code>格式解析成字符串
     *
     * @param date 待格式化的日期对象
     * @return 格式化的字符串
     */
    public static String formatWeb(Date date) {
        return format(date, WEB_FORMAT);
    }

    /**
     * 把日期字符串按照<code>yyyy-MM-dd</code>格式，进行格式化
     *
     * @param dateStr 待格式化的日期字符串
     * @param formatIn 输入的日期字符串的格式
     * @return 格式化的字符串
     * @throws ParseException
     */
    public static String formatWeb(String dateStr, String formatIn) throws IllegalArgumentException {
        return format(dateStr, formatIn, WEB_FORMAT);
    }

    /**
     * 把日期对象按照<code>yyyyMM</code>格式解析成字符串
     *
     * @param date 待格式化的日期对象
     * @return 格式化的字符串
     */
    public static String formatMonth(Date date) {

        return format(date, MONTH_FORMAT);
    }

    /**
     * 把日期对象按照<code>HHmmss</code>格式解析成字符串
     *
     * @param date 待格式化的日期对象
     * @return 格式化的字符串
     */
    public static String formatTime(Date date) {
        return format(date, TIME_FORMAT);
    }

    /**
     * 获取yyyyMMddHHmmss+n位随机数格式的时间戳
     *
     * @return
     */
    public static String getTimestamp() {
        return formatCurrent(LONG_FORMAT);
    }

    /**
     * 根据日期格式返回昨日日期
     *
     * @param format
     * @return
     */
    public static String getYesterdayDate(String format) {
        return format(DateTime.now().minusDays(1).toDate(), format);
    }

    /**
     * UTC 时间转换
     *
     * @param dateStr
     * @return
     */
    public static String parseUTCDate(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        if (StringUtils.containsIgnoreCase(dateStr, "T")) {
            SimpleDateFormat df = null;
            if (StringUtils.containsIgnoreCase(dateStr, ".000Z")) {
                df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.000Z'");
                df.setTimeZone(TimeZone.getTimeZone("UTC"));
                try {
                    return df.parse(dateStr).toString();
                } catch (ParseException e) {
                    logger.error(dateStr, e);
                    return dateStr;
                }
            }

            if (StringUtils.containsIgnoreCase(dateStr, "Z")) {
                df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
                df.setTimeZone(TimeZone.getTimeZone("UTC"));
                try {
                    return df.parse(dateStr).toString();
                } catch (ParseException e) {
                    logger.error(dateStr, e);
                    return dateStr;
                }
            }

        }

        return dateStr;
    }

    /**
     * 获取当前时间
     * @return
     */
    public static Date getCurrentDate() {
        return DateTime.now().toDate();
    }

}
